﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PerformanceAssessment.Models;
using System.Data.Objects.SqlClient;
using System.Net.Mail;
using System.Web.Security;
using System.Collections;
using System.Web.Routing;
using System.Web.Profile;
using MvcMembership;
using MvcMembership.Settings;
using VacationsRequest.Areas.MvcMembership.Models.UserAdministration;

namespace PerformanceAssessment.Controllers
{
    public class EmployeesController : Controller
    {
        private PerformanceAssessmentDB db = new PerformanceAssessmentDB();

        private const string ResetPasswordBody = "Your new password is: ";
        private const string ResetPasswordSubject = "Your New Password";
        private readonly IRolesService _rolesService;
        private readonly ISmtpClient _smtpClient;
        private readonly IMembershipSettings _membershipSettings;
        private readonly IUserService _userService;
        private readonly IPasswordService _passwordService;

        public EmployeesController()
            : this(new AspNetMembershipProviderWrapper(), new AspNetRoleProviderWrapper(), new SmtpClientProxy())
        {
        }

        public EmployeesController(AspNetMembershipProviderWrapper membership, IRolesService roles, ISmtpClient smtp)
            : this(membership.Settings, membership, membership, roles, smtp)
        {
        }

        public EmployeesController(
            IMembershipSettings membershipSettings,
            IUserService userService,
            IPasswordService passwordService,
            IRolesService rolesService,
            ISmtpClient smtpClient)
        {
            _membershipSettings = membershipSettings;
            _userService = userService;
            _passwordService = passwordService;
            _rolesService = rolesService;
            _smtpClient = smtpClient;
        }

        public ActionResult CreateUsers()
        {
            var employees = db.Employees;

            foreach (Employee emp in employees)
            {
                if (Membership.GetUserNameByEmail(emp.Email) == null)
                {
                    _userService.Create(
                            emp.Email,
                            "Welcome1",
                            emp.Email,
                            "what?",
                            "none",
                            true);
                }
            }

            return RedirectToAction("Index");
        }
        //
        // GET: /Employees/

        [Authorize(Roles = "Administrator")]
        public ActionResult Index(string sortOrder, bool? activeBool, string teamString, string searchString)
        {

            if (Session["EmployeeChanged"] != null)
            {
                ViewBag.EmployeeChangedMessage = Session["EmployeeChanged"].ToString();
                Session["EmployeeChanged"] = null;
            }

            if (activeBool == null)
            {
                activeBool = true;
            }

            var TeamLst = new List<string>();
            var TeamQry = from d in db.Teams
                          orderby d.ID
                          select d.Name;
            TeamLst.AddRange(TeamQry.Distinct());
            ViewBag.teamString = new SelectList(TeamLst);


            var allTeams = db.Teams.ToArray();
            var allEmployees = db.Employees.ToArray();


            var employees = from u in allEmployees
                            join t in allTeams on u.IdTeam equals t.ID
                            select new EmployeeList
                            {
                                ID = u.ID,
                                Team = t.Name,
                                Ced = u.Ced,
                                Name = u.FirstName + " " + u.FirstLastName + " " + u.SecondLastName,
                                Active = u.Active,
                                Email = u.Email,
                                StartDate = u.StartDate
                            };

            if (!String.IsNullOrEmpty(searchString))
            {
                employees = employees.Where(s => s.Name.ToLower().Contains(searchString.ToLower()));
            }

            if (!String.IsNullOrEmpty(teamString))
            {
                employees = employees.Where(x => x.Team == teamString);
            }

            employees = employees.Where(x => x.Active == activeBool);

            ViewBag.TeamSortParm = String.IsNullOrEmpty(sortOrder) ? "Team desc" : "";
            ViewBag.NameSortParm = sortOrder == "Name" ? "Name desc" : "Name";
            ViewBag.IdSortParm = sortOrder == "Ident" ? "Ident desc" : "Ident";
            ViewBag.ActiveSortParm = sortOrder == "Active" ? "Active desc" : "Active";
            ViewBag.EmailSortParm = sortOrder == "Email" ? "Email desc" : "Email";
            ViewBag.StartDateSortParm = sortOrder == "StartDate" ? "StartDate desc" : "StartDate";

            switch (sortOrder)
            {
                case "Team desc":
                    employees = employees.OrderByDescending(s => s.Team);
                    break;
                case "Name":
                    employees = employees.OrderBy(s => s.Name);
                    break;
                case "Name desc":
                    employees = employees.OrderByDescending(s => s.Name);
                    break;
                case "Ident":
                    employees = employees.OrderBy(s => s.Ced);
                    break;
                case "Ident desc":
                    employees = employees.OrderByDescending(s => s.Ced);
                    break;
                case "Active":
                    employees = employees.OrderBy(s => s.Active);
                    break;
                case "Active desc":
                    employees = employees.OrderByDescending(s => s.Active);
                    break;
                case "Email":
                    employees = employees.OrderBy(s => s.Email);
                    break;
                case "Email desc":
                    employees = employees.OrderByDescending(s => s.Email);
                    break;
                case "StartDate":
                    employees = employees.OrderBy(s => s.StartDate);
                    break;
                case "StartDate desc":
                    employees = employees.OrderByDescending(s => s.StartDate);
                    break;
                default:
                    employees = employees.OrderBy(s => s.Team);
                    break;
            }

            return View(employees);
        }

        public ActionResult SendEmail()
        {
            System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient();

            MailMessage msg = new MailMessage();

            msg.To.Add("jmendez@outcoding.com");
            msg.Body = "This is the Email Content for you to test";
            msg.Subject = "Vacation Request - Action Required";
            msg.Priority = MailPriority.High;
            msg.IsBodyHtml = true;


            smtp.Send(msg);

            return RedirectToAction("Index");
        }


        [HttpPost]
        public string Index(FormCollection fc, string searchString)
        {
            return "<h3> From [HttpPost]SearchIndex: " + searchString + "</h3>";
        }

        //
        // GET: /Employees/Details/5
        [Authorize(Roles = "Administrator")]
        public ViewResult Details(int id)
        {
            Employee employee = db.Employees.Find(id);

            ViewBag.ManagerName = (from u in db.Managers
                                   where u.ID == employee.IdManager
                                   select u.FirstName + " " + u.LastName).First();

            ViewBag.TeamName = (from u in db.Teams
                                where u.ID == employee.IdTeam
                                select u.Name).First();

            ViewBag.PositionName = (from u in db.Positions
                                    where u.ID == employee.IdPosition
                                    select u.Name).First();

            List<string> approverNames = new List<string>(Roles.GetUsersInRole("Approver"));

            List<SysUsers> approvers = new List<SysUsers>();
            foreach (string mname in approverNames)
            {
                SysUsers adminUser = new SysUsers();

                adminUser.Name = mname;
                adminUser.ID = (Guid)Membership.GetUser(mname).ProviderUserKey;

                approvers.Add(adminUser);
            }

            var tapprovers = approvers.Where(y => y.ID == employee.IdUserApprover);

            ViewBag.ApproverName = tapprovers.Select(x => x.Name).FirstOrDefault();

            return View(employee);
        }

        [Authorize]
        public ActionResult Vacations(int id)
        {
            Employee employee = db.Employees.Find(id);

            return View(employee);
        }

        //
        // GET: /Employees/Create
        [Authorize]
        public ActionResult Create()
        {
            Employee newEmployee = new Employee();

            var selectOptions = from u in db.Managers
                                select new SelectListItem
                                {
                                    Value = SqlFunctions.StringConvert((double)u.ID).Trim(),
                                    Text = u.FirstName + " " + u.LastName
                                };

            ViewBag.Managers = new SelectList(selectOptions, "Value", "Text", -1);

            ViewBag.Teams = new SelectList(db.Teams.OrderBy(p => p.ID), "ID", "Name", -1);

            ViewBag.Positions = new SelectList(db.Positions.OrderBy(p => p.ID), "ID", "Name", -1);

            List<string> approverNames = new List<string>(Roles.GetUsersInRole("Approver"));
            List<SysUsers> approvers = new List<SysUsers>();
            foreach (string mname in approverNames)
            {
                SysUsers adminUser = new SysUsers();

                adminUser.Name = mname;
                adminUser.ID = (Guid)Membership.GetUser(mname).ProviderUserKey;

                approvers.Add(adminUser);
            }
            newEmployee.Approvers = approvers.Select(x => new SelectListItem
            {
                Value = x.ID.ToString(),
                Text = x.Name
            });

            return View(newEmployee);
        }

        //
        // POST: /Employees/Create
        [Authorize]
        [HttpPost]
        public ActionResult Create(Employee employee)
        {
            if (ModelState.IsValid)
            {
                db.Employees.Add(employee);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(employee);
        }

        public ActionResult ResetPassword()
        {
            return View();
        }

        [HttpPost]
        public ActionResult ResetPassword(ResetPaswordFields passFields)
        {

            var mu = Membership.GetUser(passFields.UserName);

            if (mu != null)
            {

                var newPassword = _passwordService.ResetPassword(mu);

                var body = ResetPasswordBody + newPassword;
                var msg = new MailMessage();
                msg.To.Add(mu.Email);
                msg.Subject = ResetPasswordSubject;
                msg.Body = body;
                _smtpClient.Send(msg);

                var profile = ProfileBase.Create(mu.UserName);
                profile.SetPropertyValue("isNewUser", true);
                profile.Save();
            }

            return RedirectToAction("LogOff", "Account");
        }

        //
        // GET: /Employees/Edit/5
        [Authorize]
        public ActionResult Edit(int id)
        {
            Employee employee = db.Employees.Find(id);

            var selectOptions = from u in db.Managers
                                select new SelectListItem
                                {
                                    Value = SqlFunctions.StringConvert((double)u.ID).Trim(),
                                    Text = u.FirstName + " " + u.LastName
                                };

            ViewBag.Managers = new SelectList(selectOptions, "Value", "Text", employee.IdManager);

            ViewBag.Teams = new SelectList(db.Teams.OrderBy(p => p.ID), "ID", "Name", employee.IdTeam);

            ViewBag.Positions = new SelectList(db.Positions.OrderBy(p => p.ID), "ID", "Name", employee.IdPosition);

            List<string> approverNames = new List<string>(Roles.GetUsersInRole("Approver"));
            List<SysUsers> approvers = new List<SysUsers>();
            foreach (string mname in approverNames)
            {
                SysUsers adminUser = new SysUsers();

                adminUser.Name = mname;
                adminUser.ID = (Guid)Membership.GetUser(mname).ProviderUserKey;

                approvers.Add(adminUser);
            }
            employee.Approvers = approvers.Select(x => new SelectListItem
            {
                Value = x.ID.ToString(),
                Text = x.Name
            });

            return View(employee);
        }

        //
        // POST: /Employees/Edit/5
        [Authorize]
        [HttpPost]
        public ActionResult Edit(Employee employee)
        {
            if (ModelState.IsValid)
            {
                db.Entry(employee).State = EntityState.Modified;
                db.SaveChanges();
                Session["EmployeeChanged"] = "The details for " + (employee.FirstName + " " + employee.FirstLastName + " " + employee.SecondLastName).Trim() + " have been updated.";
                return RedirectToAction("Index");
            }
            return View(employee);
        }

        //
        // GET: /Employees/Delete/5
        [Authorize]
        public ActionResult Delete(int id)
        {
            Employee employee = db.Employees.Find(id);

            ViewBag.ManagerName = (from u in db.Managers
                                   where u.ID == employee.IdManager
                                   select u.FirstName + " " + u.LastName).First();

            ViewBag.TeamName = (from u in db.Teams
                                where u.ID == employee.IdTeam
                                select u.Name).First();

            ViewBag.PositionName = (from u in db.Positions
                                    where u.ID == employee.IdPosition
                                    select u.Name).First();

            return View(employee);
        }

        //
        // POST: /Employees/Delete/5
        [Authorize]
        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {
            Employee employee = db.Employees.Find(id);
            db.Employees.Remove(employee);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }

    }
}